<template>
  <MLayoutPage v-model:loading="loading" bottomClass="bg-grey-1" classes="traffic-control-steps" topClass="bg-grey-1">
    <template v-slot:top>
      <q-stepper ref="stepper" v-model="currentStep" alternative-labels animated class="bg-transparent q-pb-md"
                 color="primary" flat>
        <q-step v-for="step in steps" :key="step.name" :active-icon="step.icon" :done="step.name < currentStep"
                class="no-padding" v-bind="step"></q-step>
      </q-stepper>
    </template>
    <template v-slot:default>
      <q-tab-panels v-model="currentStep" animated class="bg-white-6">
        <q-tab-panel :name="1" class="row justify-center">
          <qx-form ref="FormRef" v-model="formInfo" :option="formOption"></qx-form>
        </q-tab-panel>
        <q-tab-panel :name="2">
          <component :is="animeComponent">
            <template v-slot:start>
              <qx-select ref="StartArea" v-model="formInfo.beginAreaCode" :options="controlAreas"
                         :placeholder="`${$t('MapCore.StartArea')}`" :props="areaProps"
                         :rules="[val => val || `${$t('PleaseSelect')}${$t('MapCore.StartArea')}`]" dense no-error-icon
                         outlined>
                <template v-slot:before>
                  <i class="text-red text-weight-bold">*</i>
                </template>
              </qx-select>
            </template>

            <template v-for="(point, index) in controlPoints" :key="index" v-slot:[`inner_${index}`]>
              <q-btn color="primary" outline unelevated @click="handleSiteCfg(point, index)">
                {{ getTitle(index) }}
                <q-badge v-if="point.ctrPointCode" class="bg-white-6" floating>
                  <q-icon color="positive" name="check_circle_outline"></q-icon>
                </q-badge>
              </q-btn>
            </template>

            <template v-slot:end>
              <qx-select ref="TargetArea" v-model="formInfo.endAreaCode" :options="controlAreas"
                         :placeholder="`${$t('MapCore.TargetArea')}`" :props="areaProps"
                         :rules="[val => val || `${$t('PleaseSelect')} ${$t('MapCore.TargetArea')}`]" dense
                         no-error-icon outlined>
                <template v-slot:before>
                  <i class="text-red text-weight-bold">*</i>
                </template>
              </qx-select>
            </template>
          </component>
        </q-tab-panel>
      </q-tab-panels>
    </template>
    <template v-slot:bottom>
      <div class="q-pt-md row items-center justify-end q-gutter-x-md">
        <q-btn v-if="currentStep < steps.length" icon="mdi-skip-next" outline text-color="primary" unelevated
               v-bind="menuBind" @click="handleContinue">{{ $t('NextStep') }}
        </q-btn>
        <q-btn v-if="currentStep > 1" :label="$t('GoBack')" outline text-color="primary" unelevated v-bind="menuBind"
               @click="handleReturn"></q-btn>
        <q-btn v-if="currentStep === steps.length" :label="$t('Submit')" color="primary" icon="published_with_changes"
               unelevated v-bind="menuBind" @click="submitAjax"></q-btn>
        <q-btn :label="$t('Close')" icon="cancel_schedule_send" outline text-color="primary" v-bind="menuBind"
               @click="handleClose"></q-btn>
      </div>
    </template>
  </MLayoutPage>
  <q-modal v-model="siteCfgVisible" :header="getTitle(siteIndex)" width="500" @beforeClose="handleClose"
           @confirm="submitForm">
    <qx-form ref="siteFormRef" v-model="siteFormInfo" :option="siteOption"></qx-form>
  </q-modal>
</template>
<script setup>
import { i18n, toI18nName } from 'boot/i18n.js'
import { postAPI, putAPI } from 'src/api/index.js'
import { getDictData, getRemoteData } from 'src/enum/ajaxRemoteData.js'
import { createWarnTips, isJSON } from 'src/utils/utils.js'
import Carry0 from 'src/views/RCSCore/TrafficControlAnime/Carry0.vue'
import Carry1 from 'src/views/RCSCore/TrafficControlAnime/Carry1.vue'
import Carry2 from 'src/views/RCSCore/TrafficControlAnime/Carry2.vue'
import Carry3 from 'src/views/RCSCore/TrafficControlAnime/Carry3.vue'
import Carry5 from 'src/views/RCSCore/TrafficControlAnime/Carry5.vue'
import CarryOther from 'src/views/RCSCore/TrafficControlAnime/CarryOther.vue'
import { computed, ref, watch } from 'vue'
import pointJson from 'src/i18n/TrafficControlCore/ZH_CN.json'

const props = defineProps({
  rowInfo: { type: Object, default: () => ({}) }, readonly: Boolean, tcrModes: { type: Array, default: () => [] }
})
const isRefresh = defineModel('isRefresh', { type: Boolean, default: false })
const modalVisible = defineModel('modelValue', { type: Boolean, default: false })

const prefix = 'TrafficCTRL'
const APIList = ref([])
const formInfo = ref({})
const FormRef = ref(null)
const siteIndex = ref(-1)
const loading = ref(false)
const currentStep = ref(1)
const tcrDevices = ref([])
const StartArea = ref(null)
const siteFormInfo = ref({})
const TargetArea = ref(null)
const controlAreas = ref([])
const siteFormRef = ref(null)
const controlPoints = ref([])
const siteCfgVisible = ref(false)
const areaProps = { label: 'areaName', value: 'areaCode' }
getDictData('AGV_LINKED_DEVICE').then(data => (tcrDevices.value = data))
const animeComponent = computed(() => {
  if (!formInfo.value.tcrModeCode) return void 0
  if (formInfo.value.tcrModeCode === '0') return Carry0
  if (formInfo.value.tcrModeCode === '1') return Carry1
  if (formInfo.value.tcrModeCode === '2') return Carry2
  if (formInfo.value.tcrModeCode === '3') return Carry3
  if (formInfo.value.tcrModeCode === '5') return Carry5
  return CarryOther
})
const menuBind = computed(() => ({ 'no-wrap': true, padding: '.4rem 1rem', loading: loading.value }))
const steps = computed(() => {
  return [{
    title: i18n.t('Misc.TrafficControlCfgTip1'), name: 1, icon: 'branding_watermark'
  }, {
    title: i18n.t('Misc.TrafficControlCfgTip2'), name: 2, icon: 'mdi-movie-open-play'
  }]
})
const formOption = computed(() => {
  return {
    span: 24, labelWidth: 120,
    column: [{
      label: `${i18n.t('Misc.ScenarioName')}`, field: 'tcrName', required: true
    }, {
      label: `${i18n.t('TaskCore.RelatedTaskTemplateCode')}`, field: 'mapName', required: true
    }, {
      label: `${i18n.t('AGVCore.RelatedDeviceCode')}`, field: 'deviceIndex', type: 'select', required: true,
      props: { label: toI18nName('labelZhCn'), value: 'value' }, options: tcrDevices.value, nonValiValue: true
    }, {
      label: `${i18n.t('Misc.ControlMode')}`, field: 'tcrModeCode', type: 'select', required: true,
      props: { label: toI18nName('labelZhCn'), value: 'value' }, options: props.tcrModes,
      change: updateTcrMode
    }, {
      label: `${i18n.t('Misc.ControlModeRule')}`, field: 'remark', type: 'textarea', readonly: true,
      placeholder: i18n.t('Misc.ControlModeRuleTips')
    }]
  }
})
const siteOption = computed(() => {
  return {
    span: 23, labelWidth: 120,
    column: [{
      label: `${i18n.t('MapCore.StationName')}`, field: 'ctrPointCode', required: true
    }, {
      label: `${i18n.t('RCSCore.InteractiveInterface')}`, field: 'sdaiCode', type: 'select',
      options: APIList.value, props: { label: toI18nName('sdaiNameZhCn'), value: 'sdaiCode' }, required: true
    }, {
      label: `${i18n.t('RCSCore.InterfaceParams')}`, field: 'handleExtraParam', type: 'textarea',
      rules: [val => isJSON(val) || `${i18n.t('MustJSON')}`], tips: `${i18n.t('MustJSON')}`, maxlength: 5000
    }, {
      label: `${i18n.t('Misc.ExecTiming')}`, field: 'notifyMethodType',
      tips: `${i18n.t('RCSCore.RCSNotificationTips')}`
    }, {
      label: `${i18n.t('MapCore.StationRackCode')}`, field: 'shelvesCode',
      tips: `${i18n.t('MapCore.StationRackSlotTips')}`
    }, {
      label: `${i18n.t('MapCore.StationSlotCode')}`, field: 'storageCode',
      tips: `${i18n.t('MapCore.StationRackSlotTips')}`
    }]
  }
})

const getTitle = index => {
  if (index === -1 || !formInfo.value.tcrModeCode) return ''
  return i18n.t(`${prefix}${formInfo.value.tcrModeCode}.Tip${index}`)
}
const handleSiteCfg = (point, index) => {
  siteIndex.value = index
  siteFormInfo.value = point
  siteCfgVisible.value = true
  getRemoteData('traffic_ctrl_api', '/yfagv/api/sdaiAgvTaskCallback/list').then(data => (APIList.value = data))
}
const updateTcrMode = (val, list = [], configPoints) => {
  formInfo.value.remark = list[0]?.remark
  if (!val) return
  if (configPoints) controlPoints.value = configPoints.filter(el => el.ctrPointCode)
  else controlPoints.value = new Array(Object.keys(pointJson[`${prefix}${val}`]).length).fill({})
}
const handleReturn = () => {
  if (currentStep.value === 1) return
  currentStep.value--
}
const handleContinue = () => {
  if (currentStep.value === steps.value.length) return
  if (props.readonly) return currentStep.value++
  FormRef.value && FormRef.value.validate((_, done) => {
    currentStep.value++
    done()
    getRemoteData('traffic_control_area', '/yfagv/api/mapArea/list').then(data => (controlAreas.value = data))
  })
}
const handleClose = () => {
  FormRef.value && FormRef.value.onReset()
  siteFormRef.value && siteFormRef.value.onReset()
  modalVisible.value = false
  siteCfgVisible.value = false
}
const submitAjax = () => {
  if (!StartArea.value || !StartArea.value.validate()) return
  if (!TargetArea.value || !TargetArea.value.validate()) return
  const form = formInfo.value, configSplitTaskList = []
  form.endAreaName = null
  form.beginAreaName = null
  form.configSplitTasks = null
  form.isEnable = form.isEnable || '1'
  form.splitTaskExecType = form.splitTaskExecType || '1'
  form.configPointsList = [{ ctrPointCode: '' }, ...controlPoints.value, { ctrPointCode: '' }]

  let i = 0
  const NUM = controlPoints.value.length
  for (i; i < NUM; i++) {
    const el = controlPoints.value[i]
    if (!el.ctrPointCode) {
      const title = i18n.t('Misc.TrafficControlCfgSubmitTips', { name: getTitle.value(i) })
      return createWarnTips({ title })
    }
    if (i === 0) {
      configSplitTaskList.push({ concurrentTasks: -1, startPositionCode: '', endPositionCode: el.ctrPointCode })
      continue
    }
    if (i === NUM - 1) {
      configSplitTaskList.push({ concurrentTasks: -1, startPositionCode: el.ctrPointCode, endPositionCode: '' })
      continue
    }
    configSplitTaskList.push({
      concurrentTasks: 1, startPositionCode: el.ctrPointCode, endPositionCode: controlPoints.value[i + 1].ctrPointCode
    })
  }
  form.configSplitTaskList = configSplitTaskList
  loading.value = true
  const API = formInfo.value.id ? putAPI : postAPI
  API('/yfagv/api/tcrConfig', form, () => {
    loading.value = false
    isRefresh.value = true
    modalVisible.value = false
  }, () => loading.value = false)
}
const submitForm = mDone => {
  siteFormRef.value && siteFormRef.value.validate((form, done) => {
    controlPoints.value[siteIndex.value] = form
    done()
    mDone()
  }, () => mDone(false))
}
watch(modalVisible, val => {
  if (!val) return
  currentStep.value = 1
  formInfo.value = props.rowInfo || {}
  const { configPointsList, tcrModeCode } = formInfo.value
  updateTcrMode(tcrModeCode, props.tcrModes.filter(el => el.value === tcrModeCode), configPointsList)
}, { immediate: true })
</script>